#include "file_processor.h"

#include <windows.h>
#include <tchar.h> 
#include <stdio.h>
#include <strsafe.h>

vector<string> File_processor::Get_files(wstring folder_path)
{
	return Get_cpp_related_files(Get_all_files(folder_path));
}

vector<string> File_processor::Get_all_files(wstring folder_path)
{
	vector<string> result; //the result
	WIN32_FIND_DATA find_data; //the find data returned from win32 function
	
	//store the folder_path and use it to make absolute path later
	wstring original_folder_path(folder_path);
	original_folder_path += L"\\";

	//converts the folder_path to Win32 compatible format and add a "*", asking windows to query all files within
	TCHAR directory[MAX_PATH];
	StringCchCopy(directory, MAX_PATH, folder_path.c_str());
	StringCchCat(directory, MAX_PATH, TEXT("\\*")); //append a "\*" to the directory

	HANDLE find_handle = INVALID_HANDLE_VALUE;
	find_handle = FindFirstFile(directory, &find_data); //find the first file (any extension) within folder_path
	
	if (INVALID_HANDLE_VALUE == find_handle)
	{
		return result; //return an empty result
	}
	else
	{
		do
		{
			if (find_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) //the found "file" is actually a directory
			{				
				wstring wstr_directory(find_data.cFileName);				

				if (( wstr_directory != L"." ) && (wstr_directory != L"..")) //no infinte loop encountered because it can't detect MyComputer & User folder
				{
					wstr_directory = original_folder_path + wstr_directory; //make an absolute path of the sub directory
					vector<string> sub_directory_result = Get_all_files(wstr_directory); //and recursively search for all files within it
					result.insert(result.end(), sub_directory_result.begin(), sub_directory_result.end()); //add the sub dir result to the current result
				}
			}
			else //when it's really a file
			{
				//determine the file size for find_data (MSDN code)
				LARGE_INTEGER filesize;
				filesize.LowPart = find_data.nFileSizeLow;
				filesize.HighPart = find_data.nFileSizeHigh;

				//make an absolute path to the file and add it to the current result
				wstring wstr_file(find_data.cFileName);
				wstr_file = original_folder_path + wstr_file;
				string file(wstr_file.length(), ' ');
				std::copy(wstr_file.begin(), wstr_file.end(), file.begin()); //this generate warning as a wchar is being casted to a char

				result.push_back(file);
			}
		}
		while (FindNextFile(find_handle, &find_data) != 0); //find the next available file/folder
	}

	return result;
}

vector<string> File_processor::Get_cpp_related_files(vector<string> all_files)
{
	vector<string> result;

	for (vector<string>::iterator iter = all_files.begin(); iter != all_files.end(); iter++)
	{
		string file_path = *iter; //the absolute path

		//get the filename
		size_t found_pos = file_path.find_last_of("/\\"); //find the last "\" or "/", which split the path into folder path & file name
		string filename = file_path.substr(found_pos + 1); //take the right part of the split

		//get the file extension
		found_pos = filename.find_last_of("."); //find the last ".", which indicates extension
		string extension;
		if (found_pos != string::npos) //if we can find one "." (some files doesn't have that)
			extension = filename.substr(found_pos + 1);

		if ((extension == "cpp") || (extension == "h")) //only add cpp and h files to the result
			result.push_back(file_path);
	}

	return result;
}